<?php
declare(strict_types=1);

namespace app\shop\controller;

use app\shop\enums\sms\SmsTemplateCode;
use app\shop\exception\AuthException;
use app\shop\exception\FailException;
use app\shop\exception\ParamsErrorException;
use app\shop\library\ShopAuth;
use app\shop\logic\LoginLogic;
use app\shop\validate\LoginValidate;
use ba\Captcha;
use think\response\Json;
use Throwable;

/**
 * @noinspection PhpUnused
 * @property LoginLogic $logic
 */
class LoginController extends BaseController
{
    protected string $validateClassName = LoginValidate::class;

    protected array $noNeedLogin = ['*'];

    public function __construct(LoginLogic $loginLogic)
    {
        $this->logic = $loginLogic;

        parent::__construct();
    }

    /**
     * 测试登录方法，直接传手机号
     * @return Json
     * @throws FailException
     * @noinspection PhpUnused
     */
    public function testLogin(): Json
    {
        $params = request()->param();

        $result = $this->logic->loginByPhone($params['phone']);

        return $this->success($result);
    }

    /**
     * 微信登录
     * @return Json
     * @throws ParamsErrorException|FailException|Throwable
     * @noinspection PhpUnused
     */
    public function miniAppLogin(): Json
    {
        $params = $this->postInput();

        $this->validateData($params, 'mini_app_login');

        $result = $this->logic->miniAppLogin($params);

        return $this->success($result);
    }

    /**
     * 刷新Token
     * @return Json
     * @throws AuthException
     */
    public function refresh(): Json
    {
        $token = get_auth_token(['ba', 'user', 'refresh']);
        if (!$token) {
            throw new AuthException('刷新Token不存在,请重新登录');
        }
        $result = $this->logic->refreshToken($token);

        return $this->success($result);
    }

    /**
     * 退出登录
     * @noinspection PhpUnused
     * @return Json
     */
    public function logout(): Json
    {
        ShopAuth::instance()->logout();

        return $this->success('退出成功');
    }

    /**
     * 快速登录
     * @noinspection PhpUnused
     * @return Json
     * @throws FailException
     * @throws ParamsErrorException
     */
    public function quickLogin(): Json
    {
        $params = $this->postInput();

        $this->validateData($params, 'quick_login');

        $result = $this->logic->loginByLoginCode($params['login_code']);

        return $this->success($result);
    }

    /**
     * 密码登录
     * @return Json
     * @throws FailException
     * @throws ParamsErrorException
     */
    public function password(): Json
    {
        $params = $this->postInput();

        $this->validateData($params, 'password_login');

        $result = $this->logic->loginByPassword($params);

        return $this->success($result);
    }

    /**
     * 手机号登录
     * @return Json
     * @throws FailException
     * @throws ParamsErrorException
     * @throws Throwable
     */
    public function phone(): Json
    {
        $params = $this->postInput();

        $this->validateData($params, 'phone_login');

        $this->checkSmsCode($params['sms_captcha_code'], $params['phone'] . SmsTemplateCode::USER_MOBILE_VERIFY);

        $result = $this->logic->loginByPhone($params['phone']);

        return $this->success($result);
    }

    /**
     * 注册
     * @return Json
     * @throws FailException
     * @throws ParamsErrorException|Throwable
     */
    public function register(): Json
    {
        $params = $this->postInput();

        $this->validateData($params, 'register');

        $this->checkSmsCode($params['sms_captcha_code'], $params['phone'] . SmsTemplateCode::USER_REGISTER);

        $result = $this->logic->register($params);

        return $this->success($result);
    }

    /**
     * 验证码校验
     * @param string $captchaCode
     * @param string $captchaId
     * @return void
     * @throws ParamsErrorException
     * @throws Throwable
     */
    private function checkSmsCode(string $captchaCode, string $captchaId): void
    {
        if (false === (new Captcha())->check($captchaCode, $captchaId)) {
            throw new ParamsErrorException('验证码错误');
        }
    }
}
